﻿//-----------------------------------------------------------------------
// <copyright file="AgsTiledMapResource.cs" company="WorldView Solutions Inc">
//     Copyright (c) WorldView Solutions Inc. This source is subject to the Microsoft Public License (Ms-PL). All other rights reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Specialized;
using System.Drawing;
using System.Linq;
using ESRI.ArcGIS.ADF.ArcGISServer;

namespace WorldViewSolutions.ArcGISServer.SOE.DataSources
{

    /// <summary>
    /// 
    /// </summary>
    /// <remarks></remarks>
	public class AgsTiledMapResource : TiledMapResource
	{
        /// <summary>
        /// 
        /// </summary>
		private string _soapUrl;
        /// <summary>
        /// 
        /// </summary>
		private string _restUrl;
        /// <summary>
        /// 
        /// </summary>
        private string _token = null;
        /// <summary>
        /// 
        /// </summary>
        private string _defaultMapName = null;

        /// <summary>
        /// Prevents a default instance of the <see cref="AgsTiledMapResource"/> class from being created.
        /// </summary>
        /// <remarks></remarks>
        private AgsTiledMapResource()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AgsTiledMapResource"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="restUrl">The rest URL.</param>
        /// <remarks></remarks>
		public AgsTiledMapResource(string name, string restUrl)
		{
			base.Name = name;
			_restUrl = restUrl;

            // Parse the REST url to get the token and strip out any query parameters
            Uri uri = new Uri(_restUrl);
            if (uri.Query != null)
            {
                NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(uri.Query);
                if (queryString.AllKeys.Contains("token", StringComparer.InvariantCultureIgnoreCase))
                {
                    _token = queryString["token"];
                }
            }

            _restUrl = uri.GetLeftPart(UriPartial.Path); 
            if (_restUrl.EndsWith("/"))
            {
                _restUrl = _restUrl.Remove(_restUrl.Length - 1);
            }

            _soapUrl = _restUrl.Replace("/rest/", "/");
          
			InitializeService();

			base.UrlFormat = UrlFormat.REST;
		}

        /// <summary>
        /// Initializes the service.
        /// </summary>
        /// <remarks></remarks>
		public void InitializeService()
		{
			using (MapServerProxy proxy = new MapServerProxy(_soapUrl))
			{                
                _defaultMapName = proxy.GetDefaultMapName();
                System.Diagnostics.Trace.Write("Default Map Name = " + _defaultMapName, "AgsTiledMapResource");

                base.TileCacheInfo = proxy.GetTileCacheInfo(_defaultMapName);
                base.TileImageInfo = proxy.GetTileImageInfo(_defaultMapName);

                if (TileImageInfo.CacheTileFormat.ToUpper() == "JPEG")
                {
                    TileImageInfo.CacheTileFormat = "jpg";
                }

                base.ServiceUrls = new string[] { _restUrl + "/tile" };
			}
		}

        /// <summary>
        /// Gets the tile.
        /// </summary>
        /// <param name="level">The level.</param>
        /// <param name="column">The column.</param>
        /// <param name="row">The row.</param>
        /// <param name="vdir">The vdir.</param>
        /// <param name="imageType">Type of the image.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public override Bitmap GetTile(int level, int column, int row, string vdir, string imageType)
        {
            // try to get the image using the base method which does a direct REST tile request. If it fails fall back to the soap method.
            Bitmap image = base.GetTile(level, column, row, vdir, imageType);
            if(image != null) return image;

            try
            {
                ArcGISLog.Write("Requesting tile:  " + _defaultMapName + ", " + level + ", " + row + ", " + column + ", " + imageType);
                using (MapServerProxy proxy = new MapServerProxy(_soapUrl))
                {
                    byte[] data = proxy.GetMapTile(_defaultMapName, level, row, column, imageType);
                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream(data))
                    {
                        ArcGISLog.Write("END: Requesting tile");
                        return new Bitmap(ms);
                    }
                }
            }
            catch (Exception ex)
            {
                ArcGISLog.WriteError("END: Requesting tile:  ERROR - " + ex.Message);
            }

            return null;
        }
	}
}